package com.example.demo.controller;

import com.example.demo.util.Data;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.engine.ProcessEngine;
import org.flowable.engine.ProcessEngineConfiguration;
import org.flowable.engine.history.HistoricActivityInstance;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.api.Task;
import org.flowable.task.api.history.HistoricTaskInstance;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.*;

/**
 * @Author hweiyu
 * @Description
 * @Date 2022/7/11 10:57
 */
@RestController
@RequestMapping(value = "/finance")
public class FinanceController {

    @Autowired
    private ProcessEngine processEngine;

    /**
     * 发起流程
     *
     * @param starter
     * @param cash
     * @param desc
     * @return
     */
    @GetMapping(value = "/startProcess")
    public Object startProcess(@RequestParam String starter, @RequestParam String cash, @RequestParam String desc) {
        Map<String, Object> variables = new HashMap<>();
        //发起人
        variables.put("starter", starter);
        //金额
        variables.put("cash", cash);
        //描述
        variables.put("desc", desc);
        //设置流程发起人
        processEngine.getIdentityService().setAuthenticatedUserId(starter);
        ProcessInstance processInstance =
                processEngine.getRuntimeService().startProcessInstanceByKey("finance", variables);
        processEngine.getIdentityService().setAuthenticatedUserId(null);
        return new Data()
                .add("processId", processInstance.getId())
                .add("processName", processInstance.getName());
    }

    /**
     * 我的待办任务列表
     *
     * @param user
     * @return
     */
    @GetMapping(value = "/getTaskList")
    public Object getTaskList(@RequestParam String user) {
        //获取任务列表
        List<Task> tasks = processEngine.getTaskService()
                .createTaskQuery()
                .taskAssignee(user)
                .orderByTaskCreateTime()
                .desc()
                .listPage(0, 10);
        List<Data> list = new ArrayList<>();
        for (Task task : tasks) {
            list.add(new Data()
                    .add("createTime", task.getCreateTime())
                    .add("taskId", task.getId())
                    .add("taskName", task.getName()));
        }
        return list;
    }

    /**
     * 我的已办任务列表
     */
    @GetMapping(value = "/getFinishTaskList")
    public Object getFinishTaskList(@RequestParam String user) {
        //获取任务列表
        List<HistoricTaskInstance> taskList = processEngine.getHistoryService()
                .createHistoricTaskInstanceQuery()
                .finished()
                .taskAssignee(user)
                .orderByHistoricTaskInstanceEndTime()
                .desc()
                .listPage(0, 10);
        List<Data> list = new ArrayList<>();
        for (HistoricTaskInstance historicTaskInstance : taskList) {
            list.add(new Data()
                    .add("createTime", historicTaskInstance.getCreateTime())
                    .add("taskId", historicTaskInstance.getId())
                    .add("taskName", historicTaskInstance.getName()));
        }
        return list;
    }

    /**
     * 审批
     *
     * @param taskId
     * @param approval
     * @return
     */
    @GetMapping(value = "/approval")
    public Object approval(@RequestParam String taskId, @RequestParam String user, @RequestParam String approval) {
        Task task = processEngine.getTaskService().createTaskQuery().taskAssignee(user).taskId(taskId).singleResult();
        if (null == task) {
            return new Data().add("errorMsg", "任务不存在");
        }
        Map<String, Object> vals = new HashMap<>();
        String key = "leader".equals(task.getTaskDefinitionKey()) ? "approval1" : "approval2";
        vals.put(key, String.valueOf("true".equals(approval)));
        // 认领任务，这样才能在已完成任务列表中，通过指派人查到数据
        processEngine.getTaskService().claim(taskId, user);
        processEngine.getTaskService().complete(taskId, vals);
        return new Data().add("msg", "审批通过");
    }

    /**
     * 我发起的流程
     *
     * @param user
     * @return
     */
    @GetMapping(value = "/myProcess")
    public Object myProcess(@RequestParam String user) {
        List<HistoricProcessInstance> processList = processEngine.getHistoryService()
                .createHistoricProcessInstanceQuery()
                .startedBy(user)
                .orderByProcessInstanceStartTime()
                .desc()
                .listPage(0, 10);
        List<Data> list = new ArrayList<>();
        for (HistoricProcessInstance process : processList) {
            list.add(new Data()
                    .add("startTime", process.getStartTime())
                    .add("processId", process.getId())
                    .add("processName", process.getName()));
        }
        return list;
    }

    /**
     * 生成流程进度图
     *
     * @param processId
     * @param response
     */
    @GetMapping(value = "/diagram")
    public void diagram(@RequestParam String processId, HttpServletResponse response) {
        String processDefinitionId;
        // 获取当前的流程实例
        ProcessInstance processInstance = processEngine.getRuntimeService()
                .createProcessInstanceQuery()
                .processInstanceId(processId)
                .singleResult();
        // 如果流程未结束
        if (null != processInstance) {
            // 根据流程实例ID获得当前处于活动状态的ActivityId合集
            processDefinitionId = processInstance.getProcessDefinitionId();
        }
        // 如果流程已经结束，则得到结束节点
        else {
            HistoricProcessInstance pi = processEngine.getHistoryService()
                    .createHistoricProcessInstanceQuery()
                    .processInstanceId(processId)
                    .singleResult();
            processDefinitionId = pi.getProcessDefinitionId();
        }
        // 获得已执行到的活动节点
        List<HistoricActivityInstance> highLightedFlowList = processEngine.getHistoryService()
                .createHistoricActivityInstanceQuery()
                .processInstanceId(processId)
                .orderByHistoricActivityInstanceStartTime()
                .asc()
                .list();
        List<String> highLightedFlows = new ArrayList<>();
        List<String> highLightedNodes = new ArrayList<>();
        //高亮线
        for (HistoricActivityInstance tempActivity : highLightedFlowList) {
            if ("sequenceFlow".equals(tempActivity.getActivityType())) {
                //高亮线
                highLightedFlows.add(tempActivity.getActivityId());
            } else {
                //高亮节点
                highLightedNodes.add(tempActivity.getActivityId());
            }
        }
        //获取流程图
        BpmnModel bpmnModel = processEngine.getRepositoryService().getBpmnModel(processDefinitionId);
        ProcessEngineConfiguration config = processEngine.getProcessEngineConfiguration();
        //获取自定义图片生成器
        InputStream in = config.getProcessDiagramGenerator()
                .generateDiagram(
                        bpmnModel,
                        "png",
                        highLightedNodes,
                        highLightedFlows,
                        config.getActivityFontName(),
                        config.getLabelFontName(),
                        config.getAnnotationFontName(),
                        config.getClassLoader(),
                        1.0,
                        true);
        try(OutputStream os = response.getOutputStream()) {
            BufferedImage image = ImageIO.read(in);
            response.setContentType("image/png");
            if (image != null) {
                ImageIO.write(image, "png", os);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
